import { EntityManager } from '@mikro-orm/mysql';
import { InjectEntityManager, InjectMikroORM } from '@mikro-orm/nestjs';
import { Body, Controller, Get, Post, Query, Req } from '@nestjs/common';
import { JobProjectSources } from "@entities/JobProjectSources";
import { JobTasks } from "@entities/JobTasks";
import { JsonApiResponse } from '@utils/json.api.response';
import { Users } from "@entities/Users";
import { EntitySchema, MikroORM } from '@mikro-orm/core';
import { JobProjectJobs } from "@entities/JobProjectJobs";
import { ApiTags } from '@nestjs/swagger';
import { knext } from 'knext';
import { OrderJobEnrolls } from '@databases/entities/OrderJobEnrolls';
import dayjs from 'dayjs';
import { knexPrefix } from '@databases/vo/dao-helper';
import { UserskVO } from '@databases/vo/UserVO';
import { OrderJobEnrollsVO } from '@databases/vo/OrderJobEnrollersVO';


@ApiTags('(管理员) 兼职-报名')
@Controller('enrolls')
export class EnrollsController {
    constructor(
        @InjectMikroORM('zp')
        private readonly orm: MikroORM,
        @InjectEntityManager('zp')
        private readonly em: EntityManager
    ) { }

    @Post('seed_user')
    async seedUsers(@Req() request) {
        let knex = knext(this)
        let users = await knex.fromORM(Users)
            .selectAll()
            .whereNot({ id: request.user.id })
            .orderByRaw('RAND()')
            .limit(10)

        return JsonApiResponse.object(users)
    }

    @Post('seed_create')
    async create(
        @Req() request,
        @Body('user_id') user_id,
        @Body('job_task_id') job_task_id,
        @Body('expected_job_id') expected_job_id,
    ) {
        //let user_id = request.user.id

        let knex = knext(this)

        let task = await knex.fromORM(JobProjectJobs).where({ id: expected_job_id }).getOne()

        if (!task || task.task_id != job_task_id) {
            return JsonApiResponse.ERR('职位ID错误')
        }

        let enroll = await knex.fromORM(OrderJobEnrolls)
            .findOrCreate([
                'id',
                'enroller_id',
                'job_task_id',
            ], {
                'enroller_id': user_id,
                'job_task_id': job_task_id,
            }, {
                'enroller_id': user_id,
                'job_task_id': job_task_id,
                'expected_job_id': expected_job_id
            })


        let enrolls = await knex.fromORM(OrderJobEnrolls)
            .selectAll()
            .withEntity(Users, 'enroller')
            .withEntity(JobProjectJobs, 'expectedJob')
            .where({ id: enroll[0].id })
            .populate()

        return JsonApiResponse.object(enrolls)
    }

    @Get('list')
    async list(request: Request, @Query() query) {

        const knex = knext(this)

        let result = await knex
            .fromORM(JobProjectSources)
            .select([
                '*',
                knex
                    .from('job_tasks')
                    .select([knex.raw('COUNT(*)')])
                    .where('source_id', knex.ref('job_project_sources.id'))
                    .as('task_count')
            ])
            .limit(4)
            .withEntity(JobTasks, 'tasks', async (qb) => {
                qb
                    .withEntity(JobProjectJobs, 'jobs', (qb) => {
                        qb.onlySelect(['settle_type', 'price_type'])
                    })
                    .withEntity(Users, 'creator')
                //console.log('ok')
            }).populate()

        return JsonApiResponse.new(result)
    }

    @Post('assign')
    async assignJob(@Req() request: Request,
        @Body('enroll_ids') enroll_ids,
        @Body('job_id') job_id,
        @Body('type') type,
        @Body('op') op,
        @Body('is_leader') isLeader
    ) {
        if (enroll_ids) {
            const knex = knext(this)

            // enrolls = OrderJobEnroll::with(['enroller'=>function(query){
            //     query.withBaseInfo();
            // }]).whereIn('id',enroll_ids);
            const sql = knex.fromORM(OrderJobEnrolls)

            switch (type) {
                case 'assign':
                    if (op == 'cancel') {
                        await sql.update({ 'assigned_job_at': null }).whereIn('id', enroll_ids);
                    }
                    else {
                        if (!!!job_id) return JsonApiResponse.ERR('岗位ID不存在.');

                        await sql.update({ 'assigned_job_at': dayjs().format('YYYY-MM-DD HH:mm:ss'), 'expected_job_id': job_id }).whereIn('id', enroll_ids);
                    }
                    break;
                case 'kickout':
                    if (op == 'cancel') {
                        await sql.update({ 'kickout_at': null }).whereIn('id', enroll_ids);
                    }
                    else {
                        await sql.update({ 'kickout_at': dayjs().format('YYYY-MM-DD HH:mm:ss') }).whereIn('id', enroll_ids);
                    }
                    break;
                case 'reject':
                    if (op == 'cancel') {
                        await sql.update({ 'rejected_at': null }).whereIn('id', enroll_ids);
                    }
                    else {
                        await sql.update({ 'rejected_at': dayjs().format('YYYY-MM-DD HH:mm:ss') }).whereIn('id', enroll_ids);
                    }
                    break;
                case 'signup':
                    if (op == 'cancel') {
                        await sql.update({ 'sign_up_at': null }).whereIn('id', enroll_ids);
                    }
                    else {
                        await sql.update({ 'sign_up_at': dayjs().format('YYYY-MM-DD HH:mm:ss') }).whereIn('id', enroll_ids);
                    }
                    break;
                case 'signdown':
                    if (op == 'cancel') {
                        await sql.update({ 'sign_down_at': null }).whereIn('id', enroll_ids);
                    }
                    else {
                        await sql.update({ 'sign_down_at': dayjs().format('YYYY-MM-DD HH:mm:ss') }).whereIn('id', enroll_ids);
                    }
                    break;
                case 'verified':
                    if (op == 'cancel') {
                        await sql.update({ 'verified_at': null }).whereIn('id', enroll_ids);
                    } else {
                        await sql.update({ 'verified_at': dayjs().format('YYYY-MM-DD HH:mm:ss') }).whereIn('id', enroll_ids);
                    }
                    break;
                case 'give_salary':
                    await sql.update({ 'give_salary_at': dayjs().format('YYYY-MM-DD HH:mm:ss') }).whereIn('id', enroll_ids);
                    break;
                case 'is_leader':
                    if (!isLeader) return JsonApiResponse.ERR('缺少参数');
                    await sql.update({ 'is_leader': isLeader }).whereIn('id', enroll_ids);
                    break;
                default:
                    return JsonApiResponse.ERR('该操作不存在');
            }

            const enrolls = await knex.fromORM(OrderJobEnrolls)
                .selectAll()
                .withEntity(Users, 'enroller', qb => {
                    qb.onlySelect(...knexPrefix(UserskVO.baseInfo()));
                })
                .whereIn('id', enroll_ids)
                .map((entity) => {
                    entity.state_step = OrderJobEnrollsVO.calcStepStatus(entity)
                    return entity
                })
                .onlySelect(['*'])
                .populate()

            // enrolls = OrderJobEnroll::with(['enroller'=>function(query){
            //     query.withBaseInfo();
            // }]).whereIn('id',enroll_ids)
            // .get();

            //enrolls.toQuery().update(['assigned_job_id'=>job_id]);

            // enrolls.append('state_step');
            // enrols = enrolls.toArray();
            return JsonApiResponse.new(enrolls);
        }

    }

    @Post('create_simple')
    async create_simple(@Req() request,@Body() body){
        let sql = knext(this)
        let id = await sql.fromORM(OrderJobEnrolls)
        .insert({
            ...body,
            recruiter: request.user.id,
            created_at: dayjs().format('YYYY-MM-DD HH:mm:ss'),
            updated_at: dayjs().format('YYYY-MM-DD HH:mm:ss'),
        }).getOne()

        let job = await sql.fromORM(OrderJobEnrolls).select('*').where('id',id).getOne()

        return JsonApiResponse.object(job)
    }

    @Post('update')
    async update(@Req() request: Request,
        @Body('enroll') enroll,
    ) {

        const knex = knext(this)

        // enrolls = OrderJobEnroll::with(['enroller'=>function(query){
        //     query.withBaseInfo();
        // }]).whereIn('id',enroll_ids);
        const sql = knex.fromORM(OrderJobEnrolls)

        let enroll_id = enroll.id
        delete enroll.id
        delete enroll.enroller
        delete enroll.state_step
        delete enroll.show_phone

        enroll.updated_at = enroll.updated_at ? dayjs(enroll.updated_at).format('YYYY-MM-DD HH:mm:ss') : null
        enroll.created_at = enroll.created_at ? dayjs(enroll.created_at).format('YYYY-MM-DD HH:mm:ss') : null
        enroll.assigned_job_at = enroll.assigned_job_at ? dayjs(enroll.assigned_job_at).format('YYYY-MM-DD HH:mm:ss') : null
        await sql.update(enroll).where('id', enroll_id);

        return JsonApiResponse.OK()

    }
}
